#C کلید ورود به بازار کار

دوره پروژه‌محور #C و ASP.NET Core

C#
C#
مقالات برنامه نویسی
آموزش CSS Position؛ پنج نوع موقعیت‌دهی با مثال
آموزش گام‌به‌گام CSS Position — نسخه اصلاح‌شده سایت
تصویر آموزشی پنج نوع CSS Position شامل Static Relative Absolute Fixed Sticky

در طراحی سایت، همیشه قرار نیست عناصر دقیقاً در همان جایی نمایش داده شوند که در کد HTML نوشته شده‌اند. گاهی برچسب تخفیف روی عکس محصول قرار می‌گیرد، دکمه پشتیبانی هنگام اسکرول ثابت می‌ماند یا عنوان یک بخش به بالای صفحه می‌چسبد.

برای انجام این کارها از ویژگی position در CSS استفاده می‌کنیم. این مقاله پنج حالت Position را با مثال‌های مرحله‌ای، خروجی اجراشده کنار کد کامل و آزمایشگاه تعاملی آموزش می‌دهد.

روش مطالعه و اجرای مثال‌ها: در هر گام، سمت راست نتیجه واقعی کد رو می‌بینید و سمت چپ کد کامل HTML و CSS همون نتیجه قرار داره. فایل‌های هر مرحله مستقل‌اند؛ با کپی کل کد در یک فایل .html و باز کردنش در مرورگر می‌تونید دقیقاً همون خروجی رو ببینید. کدها در باکس کد اجرا نمی‌شن؛ فقط داخل پیش‌نمایش اجرا می‌شن.

۱. CSS Position چیست و چه کاربردی دارد؟

ویژگی position مشخص می‌کند عنصر در کدام جای صفحه قرار بگیرد، مرجع موقعیتش چه باشد و هنگام اسکرول چه رفتاری داشته باشد. پنج مقدار اصلی static، relative، absolute، fixed و sticky هستند.

جریان عادی عناصر (Normal Flow) چیست؟

قبل از یادگیری Position باید بدانیم مرورگر به صورت پیش‌فرض عناصر رو چطور می‌چیند. یک div معمولی، یک عنصر بلوکی است؛ بنابراین سه div بدون Flexbox و Grid، زیر هم نمایش داده می‌شوند.

1
گام اول: نمایش عناصر در حالت طبیعی

بدون Flexbox، Grid و Position؛ جعبه‌ها طبق رفتار پیش‌فرض div زیر هم هستند.

خروجی واقعی کد در مرورگرپیش‌نمایش

جریان عادی عناصر — بدون Flexbox

۱
۲
۳

نتیجه: هر div در یک خط جداست.

سه جعبه زیر هم هستند؛ این حالت پیش‌فرض div است، نه نتیجه CSS Position.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>گام ۱: Normal Flow — سه جعبه زیر هم</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    /* در این مرحله هیچ display: flex یا position برای جعبه‌ها وجود ندارد. */
    .stage { padding: 15px; background: white; border: 2px dashed #a1c6e7; border-radius: 10px; }
    .box { width: 105px; height: 54px; margin-bottom: 10px; border-radius: 8px;
           display: grid; place-items: center; color: white; font-weight: bold;
           background: #00489a; }
    .box:nth-child(2) { background: #2086c8; }
    .box:nth-child(3) { background: #d9a127; color: #263c51; margin-bottom: 0; }
  </style>
</head>
<body>
<h1>جریان عادی عناصر — بدون Flexbox</h1>
    <div class="stage">
      <div class="box">۱</div>
      <div class="box">۲</div>
      <div class="box">۳</div>
    </div>
    <p>نتیجه: هر div در یک خط جداست.</p>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 01-normal-flow.html ذخیره کنید و فایل را با مرورگر باز کنید.

حالا بدون تغییر ترتیب HTML فقط display: flex را به والد اضافه می‌کنیم. فرزندان مستقیم والد در حالت پیش‌فرض در یک ردیف چیده می‌شوند. Flexbox یک روش چیدمان است و خودش یکی از حالت‌های Position نیست.

2
گام دوم: نمایش همان عناصر با Flexbox

فقط ویژگی display: flex به والد اضافه شده؛ جعبه‌ها کنار هم قرار می‌گیرند.

خروجی واقعی کد در مرورگرپیش‌نمایش

همان عناصر — چیدمان با Flexbox

۱
۲
۳

نتیجه: سه div با Flexbox کنار هم قرار گرفته‌اند.

چیدمان در ردیف نتیجه Flexbox است؛ هنوز هیچ Position خاصی استفاده نکردیم.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>گام ۲: Flexbox — همان سه جعبه کنار هم</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    /* تنها تغییر اصلی: فعال کردن Flexbox روی والد */
    .stage { padding: 15px; background: white; border: 2px dashed #a1c6e7; border-radius: 10px; }
    .stage { display: flex; gap: 10px; align-items: flex-start; }
    .box { width: 105px; height: 54px; margin-bottom: 10px; border-radius: 8px;
           display: grid; place-items: center; color: white; font-weight: bold;
           background: #00489a; }
    .box:nth-child(2) { background: #2086c8; }
    .box:nth-child(3) { background: #d9a127; color: #263c51; margin-bottom: 0; }
  </style>
</head>
<body>
<h1>همان عناصر — چیدمان با Flexbox</h1>
    <div class="stage">
      <div class="box">۱</div>
      <div class="box">۲</div>
      <div class="box">۳</div>
    </div>
    <p>نتیجه: سه div با Flexbox کنار هم قرار گرفته‌اند.</p>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 02-flex-layout.html ذخیره کنید و فایل را با مرورگر باز کنید.

تفاوت مهم: Normal Flow پیش‌فرض سه div رو زیر هم می‌چیند. وقتی به والد display: flex می‌دیم، آن‌ها کنار هم دیده می‌شن. در ادامه برای مقایسه انواع Position، از همین چیدمان کنار هم استفاده می‌کنیم.

۲. آشنایی با انواع Position در CSS

Position Static چیست؟ (حالت پیش‌فرض)

وقتی position: static است، عنصر در جای مشخص‌شده توسط چیدمان عادی خودش می‌ماند و top، right، bottom و left نمی‌تونند جابه‌جاش کنند. در اینجا سه جعبه با Flexbox کنار هم قرار دارند؛ Static باعث کنار هم بودنشان نشده.

3
آزمایش Static

روی جعبه ۲ مقدار top و left گذاشتیم، اما جابه‌جا نمی‌شه.

خروجی واقعی کد در مرورگرپیش‌نمایش

جابه‌جایی سه جعبه

۱
۲
۳

جعبه شماره ۲ بین جعبه‌های ۱ و ۳ باقی می‌مونه. مقدار Static پیش‌فرض عناصر HTML است.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position Static</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .stage { direction: ltr; position: relative; background: #fff;
             border: 2px dashed #a1c6e7; border-radius: 10px;
             min-height: 165px; padding: 18px; }
    .row { display: flex; gap: 12px; align-items: flex-start; }
    .box { flex: 0 0 64px; height: 56px; border-radius: 8px; background: #00489a;
           color: white; display: grid; place-items: center;  font-weight: bold; }
    .box-2 { background: #2086c8; }
    .box-3 { background: #d9a127; color: #263c51; }

    .box-2 { position: static; top: 30px; left: 30px; }
    /* top و left در حالت static جعبه را جابه‌جا نمی‌کنند. */
  </style>
</head>
<body>
<h1>جابه‌جایی سه جعبه</h1>
    <div class="stage">
      <div class="row">
        <div class="box">۱</div>
        <div class="box box-2">۲</div>
        <div class="box box-3">۳</div>
      </div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 03-static.html ذخیره کنید و فایل را با مرورگر باز کنید.

Position Relative چیست؟ (جابه‌جایی نسبت به جای اصلی)

با relative، جعبه اول جای طبیعی خودش رو پیدا می‌کنه و بعد نسبت به همون جای اولیه جابه‌جا می‌شه. فضای اولیه جعبه حفظ می‌شه و جعبه بعدی جاش رو نمی‌گیره.

4
آزمایش Relative

جعبه ۲، ۲۴ پیکسل پایین و ۱۸ پیکسل راست می‌ره؛ خط‌چین جای اولیه رو نشان می‌ده.

خروجی واقعی کد در مرورگرپیش‌نمایش

جابه‌جایی سه جعبه

۱
۲
۳

کادر خط‌چین جای اصلی جعبه ۲ است. جعبه ۳ در جای خود باقی می‌مونه.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position Relative</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .stage { direction: ltr; position: relative; background: #fff;
             border: 2px dashed #a1c6e7; border-radius: 10px;
             min-height: 165px; padding: 18px; }
    .row { display: flex; gap: 12px; align-items: flex-start; }
    .box { flex: 0 0 64px; height: 56px; border-radius: 8px; background: #00489a;
           color: white; display: grid; place-items: center;  font-weight: bold; }
    .box-2 { background: #2086c8; }
    .box-3 { background: #d9a127; color: #263c51; }

    .box-2 { position: relative; top: 24px; left: 18px; }
    /* کادر خط‌چین جای اولیه جعبه ۲ را نمایش می‌دهد. */
    .box-2::before { content: ''; position: absolute; top: -24px; left: -18px;
      width: 100%; height: 100%; border: 2px dashed #2086c8;
      border-radius: 8px; pointer-events: none; }
  </style>
</head>
<body>
<h1>جابه‌جایی سه جعبه</h1>
    <div class="stage">
      <div class="row">
        <div class="box">۱</div>
        <div class="box box-2">۲</div>
        <div class="box box-3">۳</div>
      </div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 04-relative.html ذخیره کنید و فایل را با مرورگر باز کنید.

نکته: در این مثال خط‌چین فقط یک راهنمای دیداری با ::before است. حتی اگر خط‌چین رو حذف کنید، فضای اولیه جعبه Relative همچنان در چیدمان باقی می‌مونه.

Position Absolute چیست؟ (موقعیت‌دهی نسبت به مرجع)

با absolute، عنصر از جریان عادی خارج می‌شه؛ پس جعبه ۳ می‌تونه جای قبلی جعبه ۲ رو بگیره. برای اینکه جعبه ۲ نسبت به کادر خودش موقعیت بگیره، به والد ویژگی position: relative می‌دیم و به فرزند position: absolute.

دادن relative به والد، بدون تعیین top/right/bottom/left، خود والد رو جابه‌جا نمی‌کنه؛ فقط باعث می‌شه فرزند Absolute مرجع مشخصی برای محاسبه فاصله از لبه‌ها داشته باشه.

5
آزمایش Absolute

جعبه ۲ از ردیف خارج می‌شه و ۲۴ پیکسل از بالا و ۲۰ پیکسل از راستِ والد فاصله می‌گیره.

خروجی واقعی کد در مرورگرپیش‌نمایش

جابه‌جایی سه جعبه

۱
۲
۳

جعبه‌های ۱ و ۳ کنار هم قرار می‌گیرند، چون جعبه ۲ دیگر فضای اولیه‌ای در ردیف نداره.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position Absolute</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .stage { direction: ltr; position: relative; background: #fff;
             border: 2px dashed #a1c6e7; border-radius: 10px;
             min-height: 165px; padding: 18px; }
    .row { display: flex; gap: 12px; align-items: flex-start; }
    .box { flex: 0 0 64px; height: 56px; border-radius: 8px; background: #00489a;
           color: white; display: grid; place-items: center;  font-weight: bold; }
    .box-2 { background: #2086c8; }
    .box-3 { background: #d9a127; color: #263c51; }

    .stage { position: relative; } /* والد مرجع موقعیت است */
    .box-2 { position: absolute; top: 24px; right: 20px; }
  </style>
</head>
<body>
<h1>جابه‌جایی سه جعبه</h1>
    <div class="stage">
      <div class="row">
        <div class="box">۱</div>
        <div class="box box-2">۲</div>
        <div class="box box-3">۳</div>
      </div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 05-absolute.html ذخیره کنید و فایل را با مرورگر باز کنید.

Position Fixed چیست؟ (ثابت ماندن هنگام اسکرول)

با fixed، عنصر از جریان عادی خارج می‌شه و معمولاً نسبت به پنجره مرورگر ثابت می‌مونه. مثلاً یک دکمه پشتیبانی که حتی وقتی صفحه رو پایین می‌برید، در گوشه دیده می‌شه.

6
آزمایش Fixed همراه با اسکرول

داخل پیش‌نمایش سمت راست اسکرول کنید؛ دکمه پشتیبانی در گوشه پنجره داخلی می‌مونه.

خروجی واقعی کد در مرورگرپیش‌نمایش

یک صفحه بلند

داخل همین کادر اسکرول کنید.

دکمه پشتیبانی با صفحه حرکت نمی‌کند.

پایین صفحه؛ دکمه هنوز دیده می‌شود.

پشتیبانی

در قاب مقاله، ثابت‌ماندن دکمه داخل پیش‌نمایش بازسازی شده؛ کد کامل قابل کپی از position: fixed واقعی استفاده می‌کند.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position Fixed — دکمه پشتیبانی</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    body { padding: 0; }
    .content { min-height: 1000px; padding: 18px;
               background: repeating-linear-gradient(#fff 0 55px, #edf5fd 56px); }
    .support { position: fixed; right: 18px; bottom: 18px;
               background: #00489a; color: white; padding: 9px 15px;
               border-radius: 25px; text-decoration: none; font-weight: bold; }
  </style>
</head>
<body>
<main class="content">
      <h1>یک صفحه بلند</h1>
      <p>داخل همین کادر اسکرول کنید.</p>
      <p>دکمه پشتیبانی با صفحه حرکت نمی‌کند.</p>
      <p style="margin-top:640px">پایین صفحه؛ دکمه هنوز دیده می‌شود.</p>
    </main>
    <a class="support" href="#">پشتیبانی</a>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 06-fixed.html ذخیره کنید و فایل را با مرورگر باز کنید.

در موارد خاص، ویژگی‌هایی مانند transform روی اجداد می‌تونند مرجع Fixed رو تغییر بدن؛ بنابراین Fixed همیشه در هر ساختاری نسبت به پنجره اصلی مرورگر نیست.

Position Sticky چیست؟ (چسبیدن در محدوده اسکرول)

با sticky، عنوان ابتدا در جای عادی خودش قرار داره. وقتی به لبه تعیین‌شده مثل top: 0 می‌رسه، می‌چسبه؛ ولی وقتی بخش مربوط به خودش تموم می‌شه، عنوان بخش بعدی جایگزینش می‌شه.

7
آزمایش Sticky همراه با اسکرول

در قاب سمت راست پایین برید؛ عنوان اول می‌چسبه، بعد در انتهای بخش اول کنار می‌ره.

خروجی واقعی کد در مرورگرپیش‌نمایش

عنوان چسبان بخش اول

صفحه را داخل پیش‌نمایش اسکرول کنید.

عنوان چسبان بخش دوم

عنوان قبلی با رسیدن به انتهای بخش اول کنار رفت.

بر خلاف Fixed، هر عنوان Sticky فقط در محدوده بخش خودش باقی می‌مونه.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position Sticky — عنوان بخش‌ها</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    body { padding: 0; }
    .section { height: 420px; border-bottom: 2px dashed #a1c6e7;
               background: repeating-linear-gradient(#fff 0 55px, #edf5fd 56px); }
    .section:nth-child(2) { background: #f3f9ff; }
    .title { position: sticky; top: 0; margin: 0; padding: 11px;
             background: #fcecca; color: #00489a;   }
    .section p { padding: 12px; }
  </style>
</head>
<body>
<section class="section">
      <h2 class="title">عنوان چسبان بخش اول</h2>
      <p>صفحه را داخل پیش‌نمایش اسکرول کنید.</p>
    </section>
    <section class="section">
      <h3 class="title">عنوان چسبان بخش دوم</h3>
      <p>عنوان قبلی با رسیدن به انتهای بخش اول کنار رفت.</p>
    </section>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 07-sticky.html ذخیره کنید و فایل را با مرورگر باز کنید.

برای Sticky: معمولاً باید top یا bottom مقدار غیر از auto داشته باشه، فضای کافی برای اسکرول وجود داشته باشه و ویژگی overflow اجداد درست بررسی بشه.

۳. آموزش ویژگی‌های Top، Right، Bottom و Left در CSS

بعد از انتخاب نوع Position، با چهار ویژگی top، right، bottom و left فاصله یا جابه‌جایی عنصر رو تنظیم می‌کنیم. مهمه بدانید معنای عددها به نوع Position بستگی داره: در Absolute معمولاً فاصله از لبه مرجع است؛ در Relative جابه‌جایی نسبت به جای اولیه.

ویژگیمعنی در Absolute
topفاصله از لبه بالایی مرجع
rightفاصله از لبه سمت راست مرجع
bottomفاصله از لبه پایینی مرجع
leftفاصله از لبه سمت چپ مرجع

هر جهت را جدا ببینید

8
چهار جهت با خروجی قابل مشاهده

چهار کادر مستقل داریم؛ در هر کادر جعبه فقط ۱۰ پیکسل از لبه‌ای که اسمش نوشته شده فاصله دارد.

خروجی واقعی کد در مرورگرپیش‌نمایش

فاصله ۱۰ پیکسل از هر لبه

top: 10px
top
right: 10px
right
bottom: 10px
bottom
left: 10px
left

فاصله top و bottom نسبت به لبه‌های عمودی است؛ right و left نسبت به لبه‌های افقی.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>چهار جهت position در CSS</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    .examples { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .item { background: #fff; border: 1px solid #d4e4f0; padding: 8px; border-radius: 8px; }
    .item strong { display: block;   margin-bottom: 7px; }
    .stage { position: relative; height: 96px; background: #e7f3fe;
             border: 2px dashed #9fc4e5; border-radius: 7px; direction: ltr; }
    .box { position: absolute; width: 55px; height: 35px; border-radius: 6px;
           background: #00489a; color: white; display: grid; place-items: center;   }
    .top { top: 10px; left: calc(50% - 27px); }
    .right { right: 10px; top: calc(50% - 17px); }
    .bottom { bottom: 10px; left: calc(50% - 27px); }
    .left { left: 10px; top: calc(50% - 17px); }
  </style>
</head>
<body>
<h1>فاصله ۱۰ پیکسل از هر لبه</h1>
    <div class="examples">
      <div class="item"><strong>top: 10px</strong><div class="stage"><div class="box top">top</div></div></div>
      <div class="item"><strong>right: 10px</strong><div class="stage"><div class="box right">right</div></div></div>
      <div class="item"><strong>bottom: 10px</strong><div class="stage"><div class="box bottom">bottom</div></div></div>
      <div class="item"><strong>left: 10px</strong><div class="stage"><div class="box left">left</div></div></div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 08-four-directions.html ذخیره کنید و فایل را با مرورگر باز کنید.

مقدارهای مثبت و منفی در Relative

در حالت relative، مقدار left: 15px جعبه رو ۱۵ پیکسل به سمت راست می‌بره و left: -15px برعکس به چپ حرکت می‌ده. در مثال بعدی هر دو حالت رو کنار هم می‌بینید.

9
مقایسه مقدار مثبت و منفی

دو جعبه یکسان با موقعیت اولیه خط‌چین؛ یکی چپ‌تر و دیگری راست‌تر حرکت می‌کنه.

خروجی واقعی کد در مرورگرپیش‌نمایش

مقایسه دو مقدار left

left: -15px
۲
left: 15px
۲

خط‌چین جای اصلی جعبه است.

برای Relative: top مثبت پایین، bottom مثبت بالا، left مثبت راست و right مثبت چپ می‌بره؛ عدد منفی جهت را برعکس می‌کنه.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Relative — مقدار مثبت و منفی</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    .examples { display: flex; gap: 12px; }
    .item { flex: 1; min-width: 0; background: white; padding: 10px;
            border-radius: 8px; border: 1px solid #d4e4f0; }
    .stage { margin-top: 12px; position: relative; height: 94px; border: 2px dashed #9fc4e5;
             background: #e7f3fe; display: grid; place-items: center; }
    .origin { width: 55px; height: 45px; border: 2px dashed #2086c8; border-radius: 7px; }
    .box { position: relative; width: 55px; height: 45px; display: grid; place-items: center;
           top: -2px; left: -2px; border-radius: 7px; background: #2086c8; color: white; }
    .negative { left: -15px; }
    .positive { left: 15px; }
  </style>
</head>
<body>
<h1>مقایسه دو مقدار left</h1>
    <div class="examples">
      <div class="item"><strong>left: -15px</strong><div class="stage"><div class="origin"><div class="box negative">۲</div></div></div></div>
      <div class="item"><strong>left: 15px</strong><div class="stage"><div class="origin"><div class="box positive">۲</div></div></div></div>
    </div>
    <p>خط‌چین جای اصلی جعبه است.</p>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 09-positive-negative.html ذخیره کنید و فایل را با مرورگر باز کنید.

۴. ابزار تعاملی CSS Position؛ موقعیت عناصر را خودتان تغییر دهید

تا اینجا مثال‌های مستقل رو دیدید. حالا در همین صفحه با اسلایدرها جای جعبه ۲ رو تغییر بدید، اسکرول کنید و کد HTML/CSS ساخته‌شده رو ببینید.

آزمایش پیشنهادی: ۱. نوع Position رو انتخاب کنید. ۲. مقدار یکی از چهار جهت رو تغییر بدید. ۳. در حالت Fixed و Sticky داخل کادر اسکرول کنید. ۴. کد کامل وضعیت انتخاب‌شده رو کپی و اجرا کنید.
گام اول: نوع Position را انتخاب کنید

محدوده والد (Parent)
۱
۲
۳
↓ داخل این کادر اسکرول کنید و جعبه ۲ را دنبال کنید.
ادامه اسکرول: تفاوت Fixed و Sticky را ببینید.
پایان محدوده والد؛ Sticky از اینجا به بعد نمی‌چسبد.
بیرون از محدوده والد در این نقطه Sticky خارج می‌شود، اما Fixed در پنجره پیش‌نمایش باقی می‌ماند.
پایان آزمایش — به بالای کادر برگردید.

داخل کادر بالا اسکرول کنید یا دکمه «نمایش حرکت با اسکرول» را بزنید.

با تغییر هر اسلایدر، مقدار CSS بلافاصله تغییر می‌کند. هر جهت، جهت مخالف خود را به auto برمی‌گرداند تا نتیجه برای شروع ساده‌تر باشد.

گام دوم: موقعیت جعبه شماره ۲ را تغییر دهید

کد کامل HTML + CSS همین وضعیت
مشاهده کد کامل HTML + CSS وضعیت انتخاب‌شده

در آزمایشگاه، حالت Fixed برای جلوگیری از پوشاندن بخش‌های سایت داخل قاب تعاملی شبیه‌سازی می‌شه؛ کد قابل‌کپی از position: fixed واقعی استفاده می‌کنه. برای دیدن Fixed واقعی، مثال گام ۶ رو اجرا کنید.

۵. جدول مقایسه انواع Position در CSS

نوعآیا فضای اولیه حفظ می‌شود؟مرجع حرکتکاربرد عملی
staticبلهچیدمان عادی صفحهمتن و عناصر معمولی
relativeبلهجای اولیه خودشجابه‌جایی کوچک و ساخت مرجع برای Absolute
absoluteخیربلوک مرجع؛ معمولاً والد موقعیت‌داربرچسب روی تصویر
fixedخیرمعمولاً پنجره مرورگردکمه پشتیبانی ثابت
stickyبلهموقعیت عادی و محدوده اسکرولعنوان یا منوی چسبان

در یک نگاه: Relative حرکت می‌کنه اما فضای قبلی خودش رو حفظ می‌کنه؛ Absolute از جریان عادی خارج می‌شه؛ Fixed با اسکرول معمولاً در پنجره ثابت می‌مونه و Sticky فقط در محدوده مجاز می‌چسبه.

۶. نکات مهم و اشتباهات رایج CSS Position

این بخش چند مشکل رایج در پروژه واقعی رو نشان می‌ده. کد هر مثال مستقل و قابل اجراست؛ خروجی اشتباه و نسخه اصلاح‌شده رو کنار هم بررسی کنید.

مشکل ۱: چرا Top روی جعبه اثر نمی‌کند؟

10
رفع خطای top در Static

یک جعبه با Static حرکت نمی‌کنه؛ با تغییر همون ویژگی به Relative مقدار top اثر می‌گذاره.

خروجی واقعی کد در مرورگرپیش‌نمایش

چرا top اثر نمی‌کند؟

قبل: static
۲
بعد: relative
۲

خروجی داخل قاب اجرا شده؛ برای مشاهده تغییرات، کد را کپی و در مرورگر اجرا کنید.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Static در برابر Relative</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    .examples { display: flex; gap: 12px; }
    .example { flex: 1; min-width: 0; background: white; padding: 10px; border: 1px solid #d4e4f0; border-radius: 9px; }
    .stage { min-height: 115px; padding: 12px; border: 2px dashed #a1c6e7; }
    .box { width: 55px; height: 44px; display: grid; place-items: center; border-radius: 7px;
           background: #2086c8; color: white; }
    .wrong { position: static; top: 28px; }
    .right { position: relative; top: 28px; }
    strong {   }
  </style>
</head>
<body>
<h1>چرا top اثر نمی‌کند؟</h1>
    <div class="examples">
      <div class="example"><strong>قبل: static</strong><div class="stage"><div class="box wrong">۲</div></div></div>
      <div class="example"><strong>بعد: relative</strong><div class="stage"><div class="box right">۲</div></div></div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 10-static-fix.html ذخیره کنید و فایل را با مرورگر باز کنید.

مشکل ۲: چرا برچسب تخفیف گوشه صفحه افتاده، نه گوشه کارت؟

اگر کارت مرجع موقعیت نباشه، برچسب Absolute ممکنه نسبت به بخش بزرگ‌تری از صفحه جابه‌جا بشه. مقایسه زیر رو ببینید: هر دو برچسب Absolute هستند، اما فقط کارت سمت چپِ تصویری، مرجع درستی داره.

11
رفع مشکل مرجع Absolute

در کارت اول برچسب بیرون کارت می‌افته؛ در کارت دوم با position: relative روی والد، داخل کارت قرار می‌گیره.

خروجی واقعی کد در مرورگرپیش‌نمایش

مرجع برچسب تخفیف

قبل: بدون مرجع
۲۰٪ تخفیف
بعد: کارت Relative
۲۰٪ تخفیف

در نسخه درست، با گذاشتن Relative روی کارت، خود کارت جابه‌جا نشده؛ فقط مرجع برچسب مشخص شده.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>اشتباه رایج Absolute — مرجع والد</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    body { position: relative; }
    .examples { display: flex; gap: 12px; margin-top: 10px; }
    .example { flex: 1; min-width: 0; background: white; border: 1px solid #d4e4f0;
               border-radius: 9px; padding: 9px; }
    .product { height: 130px; border: 2px dashed #9fc4e5; background: #e7f3fe;
               border-radius: 8px; margin-top: 12px; }
    .correct .product { position: relative; }
    .discount { position: absolute; top: 8px; right: 8px;  
                padding: 4px 7px; border-radius: 6px; background: #00489a; color: white; }
    .example strong {   }
  </style>
</head>
<body>
<h1>مرجع برچسب تخفیف</h1>
    <div class="examples">
      <div class="example wrong"><strong>قبل: بدون مرجع</strong><div class="product"><span class="discount">۲۰٪ تخفیف</span></div></div>
      <div class="example correct"><strong>بعد: کارت Relative</strong><div class="product"><span class="discount">۲۰٪ تخفیف</span></div></div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 11-absolute-parent-fix.html ذخیره کنید و فایل را با مرورگر باز کنید.

مشکل ۳: چرا Sticky هنگام اسکرول نمی‌چسبد؟

برای چسبیدن عمودی، معمولاً باید top یا bottom مقدار داشته باشه. در کد بعدی دو بخش قابل اسکرول داریم: اولی بدون top و دومی با top: 0. هر دو رو جداگانه اسکرول کنید.

12
رفع مشکل Sticky

هر دو کادر داخلی رو اسکرول کنید؛ عنوان سمت دارای top: 0 می‌چسبه.

خروجی واقعی کد در مرورگرپیش‌نمایش

Sticky بدون top و با top

بدون top

بدون top

اسکرول کنید

با top: 0

با top: 0

اسکرول کنید

اگر Sticky باز هم کار نکرد، ارتفاع محدوده اسکرول و overflow اجداد رو بررسی کنید.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>اشتباه رایج Sticky — نبودن top</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {   margin: 0 0 14px; }
    p { margin: 8px 0; }

    .examples { display: flex; gap: 10px; }
    .example { flex: 1; min-width: 0; }
    .scroller { height: 220px; overflow-y: auto; border: 2px solid #a1c6e7;
                border-radius: 8px; background: white; }
    .long { height: 590px; background: repeating-linear-gradient(#fff 0 50px,#edf5fd 51px); }
    .label { position: sticky; background: #fcecca; margin: 0; padding: 9px 3px;
               text-align: center; }
    .correct .label { top: 0; }
    .example strong { }
  </style>
</head>
<body>
<h3>Sticky بدون top و با top</h3>
    <div class="examples">
      <div class="example wrong"><strong>بدون top</strong>
        <div class="scroller"><div class="long"><h2 class="label">بدون top</h2><p>اسکرول کنید</p></div></div>
      </div>
      <div class="example correct"><strong>با top: 0</strong>
        <div class="scroller"><div class="long"><h2 class="label">با top: 0</h2><p>اسکرول کنید</p></div></div>
      </div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 12-sticky-top-fix.html ذخیره کنید و فایل را با مرورگر باز کنید.

مشکل ۴: وقتی دو عنصر روی هم افتادند، کدام جلو دیده می‌شود؟

با z-index می‌تونیم ترتیب نمایش دو عنصر روی هم رو در یک زمینه لایه‌بندی مشخص تعیین کنیم. برای نمایش آسان، دو کارت Absolute روی هم قرار گرفته‌اند؛ در ادامه کد کامل اون رو دارید.

13
آزمایش z-index

کارت با z-index برابر ۱۰ جلوتر از کارت با مقدار ۱ نشان داده می‌شه.

خروجی واقعی کد در مرورگرپیش‌نمایش

کدام کارت جلوتر دیده می‌شود؟

پشتی: z-index 1
جلویی: z-index 10

نکته: مقدار بزرگ‌تر همیشه به معنی جلوتر بودن از همه عناصر صفحه نیست؛ Stacking Context والدها هم اثر داره.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>z-index — ترتیب لایه‌ها</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .stage { position: relative; background: #e7f3fe; height: 210px;
             border: 2px dashed #a1c6e7; border-radius: 12px; }
    .card { position: absolute; width: 135px; height: 90px; border-radius: 9px;
            color: white; display: grid; place-items: center; font-weight: bold; }
    .back { top: 20px; right: 35px; z-index: 1; background: #00489a; }
    .front { top: 75px; right: 90px; z-index: 10; background: #2086c8; }
  </style>
</head>
<body>
<h1>کدام کارت جلوتر دیده می‌شود؟</h1>
    <div class="stage">
      <div class="card back">پشتی: z-index 1</div>
      <div class="card front">جلویی: z-index 10</div>
    </div>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 13-z-index.html ذخیره کنید و فایل را با مرورگر باز کنید.

۷. تمرین عملی CSS Position؛ ساخت برچسب تخفیف روی محصول

حالا از Relative و Absolute در یک مثال واقعی فروشگاهی استفاده می‌کنیم. این پروژه دو گام مستقل داره؛ در هر گام یک فایل کامل HTML/CSS و خروجی واقعی همون کد رو می‌بینید.

گام اول: ساخت کارت محصول و تعیین مرجع با Relative

اول کارت محصول رو با تصویر ساده، عنوان و توضیح می‌سازیم. به کارت position: relative می‌دیم؛ در این مرحله هنوز برچسبی وجود نداره. این ویژگی بدون offset، کارت رو جابه‌جا نمی‌کنه.

14
پروژه — گام اول: کارت بدون برچسب

کارت محصول رو می‌سازیم و Relative روی والد تعریف می‌کنیم.

خروجی واقعی کد در مرورگرپیش‌نمایش

کارت محصول بدون برچسب

کیف روزمره

در گام بعد، برچسب تخفیف اضافه می‌کنیم.

خروجی داخل قاب اجرا شده؛ برای مشاهده تغییرات، کد را کپی و در مرورگر اجرا کنید.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>گام ۱: کارت محصول</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .product { position: relative; width: 245px; max-width: 100%; margin: 8px auto;
               border: 1px solid #d8e6f4; border-radius: 12px;
               overflow: hidden; background: white; }
    .product-art { height: 145px; display: grid; place-items: center; background: #e7f3fe; }
    .product h2 {  margin: 10px 12px 0; }
    .product p {  margin: 5px 12px 12px; }
  </style>
</head>
<body>
<h1>کارت محصول بدون برچسب</h1>
    <article class="product">
      <div class="product-art"><svg width="144" height="115" viewBox="0 0 170 140" role="img" aria-label="تصویر کیف آبی">
        <path d="M48 48 V35 Q48 10 85 10 Q122 10 122 35 V48" fill="none" stroke="#00489A" stroke-width="9"/>
        <rect x="24" y="44" width="122" height="85" rx="16" fill="#2086C8"/>
        <rect x="36" y="59" width="98" height="56" rx="8" fill="#00489A"/>
      </svg></div>
      <h3>کیف روزمره</h3>
      <p>در گام بعد، برچسب تخفیف اضافه می‌کنیم.</p>
    </article>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 14-product-step-1.html ذخیره کنید و فایل را با مرورگر باز کنید.

گام دوم: افزودن برچسب تخفیف با Absolute

حالا یک span رو داخل کارت اضافه می‌کنیم و با position: absolute; top: 12px; right: 12px;، برچسب تخفیف رو در گوشه بالا-راست کارت قرار می‌دیم. سورس کامل مرحله دوم مستقل از مرحله اول قابل اجراست.

15
پروژه — گام دوم: محصول با برچسب تخفیف

برچسب Absolute روی والد Relative قرار می‌گیره، دقیقاً ۱۲ پیکسل از بالا و راست.

خروجی واقعی کد در مرورگرپیش‌نمایش

کارت محصول با برچسب تخفیف

۲۰٪ تخفیف

کیف روزمره

کارت محصول با برچسب تخفیف

تمرین: در کد بالا right: 12px رو به left: 12px تبدیل کنید و جای برچسب رو ببینید.

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>گام ۲: کارت محصول با برچسب تخفیف</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 0; padding: 18px; font: 16px/1.8 Tahoma, Arial, sans-serif;
           color: #263c51; background: #f5f9ff; }
    h1 {  margin: 0 0 14px; }
    p { margin: 8px 0; }

    .product { position: relative; width: 245px; max-width: 100%; margin: 8px auto;
               border: 1px solid #d8e6f4; border-radius: 12px;
               overflow: hidden; background: white; }
    .product-art { height: 145px; display: grid; place-items: center; background: #e7f3fe; }
    .product h2 {  margin: 10px 12px 0; }
    .product p {   margin: 5px 12px 12px; }

    .discount { position: absolute; top: 12px; right: 12px;
                background: #00489a; color: white; border-radius: 7px;
                padding: 4px 9px;   font-weight: bold; }
  </style>
</head>
<body>
<h1>کارت محصول با برچسب تخفیف</h1>
    <article class="product">
      <span class="discount">۲۰٪ تخفیف</span>
      <div class="product-art"><svg width="144" height="115" viewBox="0 0 170 140" role="img" aria-label="تصویر کیف آبی">
        <path d="M48 48 V35 Q48 10 85 10 Q122 10 122 35 V48" fill="none" stroke="#00489A" stroke-width="9"/>
        <rect x="24" y="44" width="122" height="85" rx="16" fill="#2086C8"/>
        <rect x="36" y="59" width="98" height="56" rx="8" fill="#00489A"/>
      </svg></div>
      <h3>کیف روزمره</h3>
      <p>کارت محصول با برچسب تخفیف</p>
    </article>
</body>
</html>

برای اجرای مستقل: روی «کپی کل کد» بزنید، متن را در فایل 15-product-final.html ذخیره کنید و فایل را با مرورگر باز کنید.

تمرین نهایی: بعد از اجرای فایل 15-product-final.html، اول right: 12px رو با left: 12px جایگزین کنید. بعد top: 12px رو به top: 30px تغییر بدید. نتیجه رو با پیش‌نمایش این صفحه مقایسه کنید.

۸. جمع‌بندی؛ چه زمانی از هر نوع Position استفاده کنیم؟

برای چیدمان معمولی نیازی نیست حتماً Position بنویسید؛ مقدار پیش‌فرض static است. برای حرکت نسبت به جای اولیه از relative، برای قرار دادن عنصر روی یک کارت از absolute، برای دکمه شناور از fixed و برای عنوانی که هنگام اسکرول می‌چسبد از sticky استفاده کنید.

قبل از انتخاب نوع Position، از خودتون بپرسید: «عنصر نسبت به کجا قرار بگیره؟» و «هنگام اسکرول چه رفتاری داشته باشه؟» پاسخ همین دو سؤال معمولاً انتخاب رو مشخص می‌کنه.

می‌خواهید طراحی سایت را اصولی یاد بگیرید؟

اگر با CSS شروع کرده‌اید و می‌خواهید HTML، CSS و JavaScript را در یک مسیر پروژه‌محور یاد بگیرید، دوره آموزش طراحی سایت تحلیل‌داده می‌تواند قدم بعدی شما باشد. کلاس‌ها حضوری و آنلاین زنده‌اند و امکان رفع اشکال مستقیم با مدرس و AnyDesk وجود دارد.

مقاله قبلی
آموزش نمایش و قابلیت دیده شدن در CSS
مقاله بعدی
آموزش CSS Float
نظرات شما

نظرات خود را ثبت کنید...